﻿#region Using

using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using MvcMall.Framework.Logging;

#endregion

namespace MvcMall.Framework.Utility
{
    ///<summary>
    ///</summary>
    public class Serializer
    {
        /// <summary>
        /// 序列化对象为XML字符串
        /// </summary>
        /// <param name="instance">需要序列化的对象</param>
        /// <returns>对象序列化之后生成的XML字符串</returns>
        public static string ObjectToXML(Object instance)
        {
            //instance = null;
            MemoryStream stream = null;
            TextWriter writer = null;
            try
            {
                stream = new MemoryStream(); // read xml in memory
                writer = new StreamWriter(stream, Encoding.UTF8);

                // get serialise object
                //XmlSerializer serializer = new XmlSerializer(typeof(Emp),"");
                XmlSerializer serializer = new XmlSerializer(instance.GetType());

                XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
                xsn.Add(string.Empty, string.Empty);

                serializer.Serialize(writer, instance, xsn); // read object
                int count = (int)stream.Length; // saves object in memory stream
                byte[] arr = new byte[count];
                stream.Seek(0, SeekOrigin.Begin);
                // copy stream contents in byte array
                stream.Read(arr, 0, count);
                //UnicodeEncoding utf = new UnicodeEncoding(); // convert byte array to string
                UTF8Encoding utf = new UTF8Encoding();
                return utf.GetString(arr).Trim();
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message, ex.StackTrace);
                throw;
            }
            finally
            {
                if (stream != null && stream.Length > 0)
                {
                    stream.Close();
                }
                if (writer != null)
                {
                    writer.Close();
                }
            }
        }

        /// <summary>
        /// 序列化对象保存到XML文件
        /// </summary>
        /// <param name="instance">需要序列化的对象</param>
        /// <param name="fileName">保存的文件名</param>
        public static void ObjectToFile(Object instance, string fileName)
        {
            StreamWriter writer = new StreamWriter(fileName);

            try
            {
                XmlSerializer serializer = new XmlSerializer(instance.GetType());
                serializer.Serialize(writer, instance);
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message, ex.StackTrace);
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }
            }
        }

        /// <summary>
        /// 从文件中将XML字符串反序列化为一个对象
        /// </summary>
        /// <param name="xmlFilePath">保存对象序列化后生成的XML字符串的文件的路径</param>
        /// <param name="t">对象的类型</param>
        /// <returns>对象的实例</returns>
        public static object FileToObject(string xmlFilePath, Type t)
        {
            FileStream readFs = null;
            Object o = null;
            try
            {
                XmlSerializer ser = new XmlSerializer(t);
                readFs = System.IO.File.OpenRead(xmlFilePath);
                XmlTextReader reader = new XmlTextReader(readFs);
                o = ser.Deserialize(reader);
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message, ex.StackTrace);
            }
            finally
            {
                if (readFs != null) readFs.Close();
            }
            return o;
        }

        /// <summary>
        /// 将XML字符串反序列化为一个对象
        /// </summary>
        /// <typeparam name="T">对象的类型</typeparam>
        /// <param name="xml">需要反序列化的XML字符串</param>
        /// <returns>对象的实例</returns>
        public static T XMLToObject<T>(string xml)
        {
            return (T)XMLToObject(xml, typeof(T));
        }

        /// <summary>
        /// 将XML字符串反序列化为一个对象
        /// </summary>
        /// <param name="xml">需要反序列化的XML字符串</param>
        /// <param name="t">对象的类型</param>
        /// <returns>对象的实例</returns>
        public static object XMLToObject(string xml, Type t)
        {
            StringReader stream = null;
            XmlTextReader reader = null;
            Object o = null;
            try
            {
                // serialise to object
                //XmlSerializer serializer = new XmlSerializer(typeof(Emp));

                XmlSerializer serializer = new XmlSerializer(t);
                stream = new StringReader(xml); // read xml data
                reader = new XmlTextReader(stream); // create reader

                //XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
                //xsn.Add("xmlns", "http://tempuri.org/XMLSchema.xsd");
                // covert reader to object
                o = serializer.Deserialize(reader);
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message, ex.StackTrace);
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
                if (reader != null)
                {
                    reader.Close();
                }
            }

            return o;
        }

        /// <summary>
        /// 将字符串写入到文件
        /// </summary>
        /// <param name="strInfo">文件内容</param>
        /// <param name="fileName">文件路径</param>
        /// <returns>true-写入成功，false-写入失败</returns>
        public static bool StringToFile(string strInfo, string fileName)
        {
            StreamWriter writer = new StreamWriter(fileName);
            try
            {
                writer.Write(strInfo);
                writer.Flush();
                writer.Close();
                return true;
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message, ex.StackTrace);
                return false;
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }
            }
        }

        /// <summary>
        /// 将字符串写入到文件
        /// </summary>
        /// <param name="strInfo">文件内容</param>
        /// <param name="fileName">文件路径</param>
        /// <param name="encodName">编码</param>
        /// <returns>true-写入成功，false-写入失败</returns>
        public static bool StringToFileByEncoding(string strInfo, string fileName, string encodName)
        {
            try
            {
                using (FileStream fs = new FileStream(fileName, FileMode.Create))
                {
                    // 创建一个 StreamWriter 对象，使用 UTF-8 编码格式
                    using (StreamWriter writer = new StreamWriter(fs, Encoding.GetEncoding(encodName)))
                    {
                        writer.Write(strInfo);
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message, ex.StackTrace);
                return false;
            }
        }

        /// <summary>
        /// 将 Stream 转成 byte[]
        /// </summary>
        public static byte[] StreamToBytes(Stream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);

            // 设置当前流的位置为流的开始
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }

        /// <summary>
        /// 将 byte[] 转成 Stream
        /// </summary>
        public static Stream BytesToStream(byte[] bytes)
        {
            Stream stream = new MemoryStream(bytes);
            return stream;
        }
    }
}